using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Net;
using System.Xml;
using System.Collections;
using System.IO;
using System.Security.Cryptography.X509Certificates;

namespace edu.stanford.hci.ideas
{
    public enum AMBIENTMODE
    {
        ACTIVE, SHOWING, AMBIENT, HIDING
    }
    /*
    public class Cert : ICertificatePolicy
    {
        public bool CheckValidationResult(ServicePoint sp,
            X509Certificate certificate, WebRequest request, int error)
        {
            Console.WriteLine("checking cert!");
            return true;
        }
    }
     */
    /**
     * this class is responsible for showing the ambient display view (Flickr photos, ambient iDeas content, etc.)
     * 
     * for now, it displays only iDeas notebook pages, taken from the montevideo server.
     * 
     * author: srk
     **/
    class Ambient
    {
        private IList imageURLs;

        private const int NUM_AMBIENT_STEPS = 300;
        private int currentAmbientStep = NUM_AMBIENT_STEPS;
        
        /*
        private String[] imageURLs = new String[] {
            "http://static.flickr.com/78/172942886_3098900eb3_b.jpg",
            "http://static.flickr.com/59/172942822_6093c5a774_b.jpg",
            "http://static.flickr.com/69/167323625_e36b0a133d_b.jpg"
            //"http://hci.stanford.edu/images/hcibanner.gif",
            //"http://hci.stanford.edu/ideas/images/collage.jpg"
        };
        */
        private String backgroundURL = "http://stanford.edu/~judywen/background.gif";
        public bool neverShow = false;

        public AMBIENTMODE currentAmbientMode = AMBIENTMODE.ACTIVE;
        private WhiteboardApp whiteboardApp;
        //private bool isShowing = false;
        private PictureBox pictureBox = new PictureBox();
        private MyPictureBox background = new MyPictureBox(null);
        private bool isAppearing = true;
        private IList notebookPageNumbers;
        private bool isDragging = false;
        private Point panelPos;
        private Point mousePos;

        public Ambient(WhiteboardApp a)
        {
            //http://api.flickr.com/services/feeds/photos_friends.gne?user_id=10797049@N00&friends=0&display_all=1&format=rss_200
            
            notebookPageNumbers = GetXMLURLsFromRSSFeed("http://montevideo.stanford.edu/servlet/NotebookRSSFeed");
            //String foo = notebookPageNumbers[0].ToString();
            //Stream testStream = GetStreamFromNotebookPageNum(notebookPageNumbers[0].ToString());
            //imageURLs = GetImageURLsFromRSSFeed("http://api.flickr.com/services/feeds/photos_friends.gne?user_id=10797049@N00&friends=0&display_all=1&format=rss_200");
            imageURLs = new ArrayList();
            imageURLs.Add("http://farm1.static.flickr.com/151/424911220_61edf63357_t.jpg");
            pictureBox.Image = ImageUtil.GetImageFromURL(imageURLs[0].ToString());
            pictureBox.Location = new System.Drawing.Point(0, 0);
            pictureBox.Name = "ambient";
            pictureBox.Size = new System.Drawing.Size(pictureBox.Image.Width, pictureBox.Image.Height);
            pictureBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseDown);
            pictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseUp);
            pictureBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureBox_MouseMove);
            whiteboardApp = a;
            background.Location = new System.Drawing.Point(0, -1200);
            background.Size = new System.Drawing.Size(1600, 1200);
            background.setAlpha(0.5f);
            background.Image = ImageUtil.GetImageFromURL(backgroundURL.ToString());
        }

        private void PictureBox_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            whiteboardApp.StopIdleTimer();
            whiteboardApp.StopShowAmbientTimer();
            isDragging = true;
            mousePos = pictureBox.PointToScreen(e.Location);
            panelPos = pictureBox.Location;
        }

        private void PictureBox_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            isDragging = false;
        }

        private void PictureBox_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e)
        {
            if (!isDragging)
                return;
            Point pos = pictureBox.PointToScreen(e.Location);
            pictureBox.Left = panelPos.X + pos.X - mousePos.X;
            pictureBox.Top = panelPos.Y + pos.Y - mousePos.Y;
        }

        public IList GetImageURLsFromRSSFeed(String strURL)
        {
            ArrayList urlList = new ArrayList();
            XmlTextReader reader = new XmlTextReader(strURL);
            while (reader.Read())
            {
                string lcname = reader.Name.ToLower();
                switch (reader.NodeType)
                {
                    case XmlNodeType.Document:
                        break;
                    case XmlNodeType.Element:
                        if (lcname == "media:content")
                        {
                            if (reader.HasAttributes)
                            {
                                urlList.Add(reader.GetAttribute("url"));
                            }
                        }
                        break;
                    case XmlNodeType.EndElement:
                        break;
                    case XmlNodeType.Text:
                        break;
                    // There are many other types of nodes, but
                    // we are not interested in them
                }
            }
            return urlList;
        }

        public IList GetXMLURLsFromRSSFeed(String strURL)
        {
            ArrayList urlList = new ArrayList();
            XmlTextReader reader = new XmlTextReader(strURL);
            while (reader.Read())
            {
                string lcname = reader.Name.ToLower();
                switch (reader.NodeType)
                {
                    case XmlNodeType.Document:
                        break;
                    case XmlNodeType.Element:
                        if (lcname == "content")
                        {
                            if (reader.HasAttributes)
                            {
                                String url = reader.GetAttribute("pagenum");
                                Console.WriteLine("RSS URL: " + url.Trim());
                                urlList.Add(url.Trim());
                            }
                        }
                        break;
                    case XmlNodeType.EndElement:
                        break;
                    case XmlNodeType.Text:
                        break;
                    // There are many other types of nodes, but
                    // we are not interested in them
                }
            }
            return urlList;
        }

        //TODO Might it make more sense to try and put all the ambient content on one page of the canvas -- in effect having it on a differeent layer?? (srk)

        private delegate void CanvasDelegate();

        //public void SetAlpha(float alpha)
        //{
        //    pictureBox.setAlpha(alpha);
        //}

        public void SetImage(String url)
        {
            Console.WriteLine("Setting image to" + url);
            Point center = new Point(whiteboardApp.ClientSize.Width / 2, whiteboardApp.ClientSize.Height / 2);

            pictureBox.Image = ImageUtil.GetImageFromURL(url);
            pictureBox.Size = new System.Drawing.Size(pictureBox.Image.Width, pictureBox.Image.Height);
            pictureBox.Location = new System.Drawing.Point(center.X - pictureBox.Size.Width / 2, center.Y - pictureBox.Size.Height / 2);
            pictureBox.Name = "ambient";
            isAppearing = true;
        }
        public AMBIENTMODE GetCurrentAmbientMode()
        {
            return currentAmbientMode;
        }

        public void SetCurrentAmbientMode(AMBIENTMODE newMode)
        {
            currentAmbientMode = newMode;
        }

        public void Show()
        {
            whiteboardApp.ClearAmbientStrokes();
            UsageLogger.logEvent(System.DateTime.Now, EVENT_TYPE.SHOW_NOTEBOOK_PAGES, whiteboardApp.GetCurrentZone(), whiteboardApp.GetPenStatus(), whiteboardApp.GetMostRecentRangerEvent(), whiteboardApp.GetMostRecentAudioEvent(), whiteboardApp.GetMostRecentCameraEvent());
            //balee +wgj - commented out anoto screen saver     
            /*
            for (int imageIndex = 0; imageIndex < 2; imageIndex++)
            {

                index = (index + 1) % notebookPageNumbers.Count;
                Stream xmlStream = GetStreamFromNotebookPageNum(notebookPageNumbers[index].ToString());
               
                whiteboardApp.LoadAnotoXML(xmlStream, imageIndex);

            }*/
             
            if (neverShow)     return;
           
            if (currentAmbientMode != AMBIENTMODE.AMBIENT){
                currentAmbientMode = AMBIENTMODE.SHOWING;
                background.Location = new System.Drawing.Point(0, background.Location.Y + 4 < 0 ? background.Location.Y + 4 : 0);
                if (background.Location.Y ==0) currentAmbientMode = AMBIENTMODE.AMBIENT;
                                  
            }

            try
            {
                //Console.WriteLine("trying to show!");
                // XXX: commented out background (balee)
                //whiteboardApp.Controls.Add(background);
                //background.BringToFront();

                whiteboardApp.Controls.Add(pictureBox);
//                pictureBox.BringToFront();
                pictureBox.SendToBack();
            }
            catch (Exception e)
            {
                Console.WriteLine("show is the culprit" + e.ToString());
            }

            Point newLocation = new Point();
            newLocation.X = (int)(((float)currentAmbientStep / (float)NUM_AMBIENT_STEPS) * (float)(whiteboardApp.GetWritingPane().Width + pictureBox.Width)) - pictureBox.Width;
            newLocation.Y = (int)(((float)whiteboardApp.GetWritingPane().Height / 2f) - (float)pictureBox.Height / 2f);
            //Console.WriteLine(newLocation);
            pictureBox.Location = newLocation;
            pictureBox.Invalidate();
            whiteboardApp.GetWritingPane().Invalidate();

            currentAmbientStep--;
            if (currentAmbientStep < 0) currentAmbientStep = NUM_AMBIENT_STEPS;

            /*
            //wgj - instead of fading in and out, just flash in, fade out.
            float alpha = pictureBox.getAlpha();
            if (isAppearing)
                    alpha = 1f;
            if (alpha == 0f)
            {
                // change images and start over
                Console.WriteLine("index = " + index);
                Console.WriteLine("imageURLs.count = " + imageURLs.Count);
                index = (index + 1) % imageURLs.Count;
                SetImage(imageURLs[index].ToString());
                isAppearing = true;
            }
            else if (alpha == 1f) isAppearing = false;

            float delta = isAppearing ? 0.02f : -0.02f;
            alpha = alpha + delta;
            //Console.WriteLine("alpha is: " + alpha);
            if (alpha > 1f) alpha = 1f;
            else if (alpha < 0f) alpha = 0f;

            pictureBox.setAlpha(alpha);
            pictureBox.Invalidate();
            */

        }

        public void Hide()
        {
            /*
            if (currentAmbientMode != AMBIENTMODE.ACTIVE){
                currentAmbientMode = AMBIENTMODE.HIDING;
                //slides background up.
                background.Location = new System.Drawing.Point(0, background.Location.Y - 4 > -1200? background.Location.Y -4 : -1200);
                if (background.Location.Y== -1200)
                {
                    try{
                        whiteboardApp.Controls.Remove(pictureBox);
                        whiteboardApp.Controls.Remove(background);
                    }
                    catch
                    {
                        Console.WriteLine("Hide is the culprit");
                    }
                    currentAmbientMode = AMBIENTMODE.ACTIVE;
                }
           }
           */
        }

        public void Invalidate()
        {
            pictureBox.Invalidate();
        }

        public Stream GetStreamFromNotebookPageNum(string tag)
        {
            String strURL = "http://ideashare.stanford.edu/servlet/ServeXML?pagenum=" + tag.Trim();
            //ServicePointManager.CertificatePolicy = new Cert();
            WebRequest wr = WebRequest.Create(strURL);
            Stream stream = wr.GetResponse().GetResponseStream();
            return stream;
            //Console.WriteLine(new StreamReader(stream).ReadToEnd());
            /*
            String strURL = "http://ideashare.stanford.edu/ServeXML?pagenum=" + tag.Trim();
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(strURL);
            request.Timeout = 5000; // 5 seconds in milliseconds
            request.ReadWriteTimeout = 20000; // allow up to 20 seconds to elapse
            // execute the request
            HttpWebResponse response = null;
            response = (HttpWebResponse)request.GetResponse();

            return response.GetResponseStream();*/
        }

    }

}
